from flask import request,jsonify
from flask.app import Flask
from typing import Any, List
import json
from apps.modules.admin.models import Post, Category, Tag
from apps.modules.admin.models.cms.cms_post_tag import post_tag
from apps.modules.admin.models.cms.cms_post_tag import post_tag
from apps.modules.admin.models.sys.sys_options import Options
from apps.extensions import db
from apps.common.utils import get_active_theme_name
from .decorator.ext_decorator import ext_decorator
@ext_decorator
def register_template_global(app: Flask):
    @app.template_global()
    def get_theme():
        """
        获取当前主题名称
        :return:
        """
        return get_active_theme_name()


    @app.template_global()
    def get_menus(menu_name):
        '''
        根据菜单名称获取菜单
        :param menu_name:菜单类型，根据类型获取不同菜单
        :return:
        '''
        try:
            # 查找菜单配置
            option = Options.query.filter_by(
                option_type='menu',
                option_name=menu_name
            ).first()

            if option:
                menu_items = json.loads(option.option_value)
                return menu_items
        except Exception as e:
            return jsonify({
                'success': False,
                'message': f'加载失败: {str(e)}'
            }), 500


    @app.template_global()
    def get_site(option_type='custom', menu_name='site_title'):
        """
        获取当前网站信息
        :param option_type:配置信息类型,此处默认custom
        :param menu_name:根据需要查询的网站信息传不同的直，比如网站标题传site_title
        :return:
        """
        option = Options.query.filter_by(
            option_type=option_type,
            option_name=menu_name
        ).first()
        return option.option_value

    @app.template_global()
    def date_format(date, pattern=None):
        """
        日期格式化
        :param date: 日期对象或字符串
        :param pattern: 日期格式，如果为None则使用默认格式
        :return: 格式化后的日期字符串
        
        支持的格式示例：
        - '%Y-%m-%d %H:%M:%S' -> 2024-01-15 14:30:25
        - '%Y-%m-%d' -> 2024-01-15
        - '%Y年%m月%d日' -> 2024年01月15日
        - '%m/%d/%Y' -> 01/15/2024
        - '%Y-%m-%d %H:%M' -> 2024-01-15 14:30
        - '%H:%M:%S' -> 14:30:25
        """
        import datetime
        
        # 如果没有提供格式，使用默认格式
        if not pattern:
            pattern = '%Y-%m-%d %H:%M:%S'
        
        # 如果日期为None，返回空字符串
        if date is None:
            return ''
        
        try:
            # 如果date是字符串，尝试转换为datetime对象
            if isinstance(date, str):
                # 尝试常见的日期格式
                common_formats = [
                    '%Y-%m-%d %H:%M:%S',
                    '%Y-%m-%d %H:%M',
                    '%Y-%m-%d',
                    '%Y/%m/%d %H:%M:%S',
                    '%Y/%m/%d %H:%M',
                    '%Y/%m/%d',
                    '%d/%m/%Y %H:%M:%S',
                    '%d/%m/%Y %H:%M',
                    '%d/%m/%Y',
                    '%m/%d/%Y %H:%M:%S',
                    '%m/%d/%Y %H:%M',
                    '%m/%d/%Y'
                ]
                
                for fmt in common_formats:
                    try:
                        date = datetime.datetime.strptime(date, fmt)
                        break
                    except ValueError:
                        continue
                else:
                    # 如果所有格式都失败，返回原始字符串
                    return date
            
            # 如果是datetime对象，直接格式化
            if isinstance(date, datetime.datetime):
                return date.strftime(pattern)
            
            # 如果是date对象，转换为datetime再格式化
            if isinstance(date, datetime.date):
                return datetime.datetime.combine(date, datetime.time.min).strftime(pattern)
            
            # 其他类型，尝试转换为字符串
            return str(date)
            
        except Exception as e:
            # 如果格式化失败，返回原始值的字符串表示
            return str(date)


    @app.template_global()
    def get_articles(
            category: str = None,  # 文章分类，分类标识逗号分割比如"python,flask,django"
            tags: str = None,  # 文章标签，文章标签逗号分割比如"python,安全,何三笔记"
            recent: bool = False,   # 最近文章，最近文章数量
            is_hot: bool = False,  # 是否热门文章,根据浏览量进行获取
            hot_num: int = 0,  # 热门文章值，比如 hot_num = 5 是获取文章浏览量大于等于5的数据
            orderby: str = '',  # 排序 按照发布时间 asc=升序 desc= 降序
            is_page: bool = False,  # 是否分页，如果is_page=True即开启分页,如果开启分页返回数据将是Paginate类型
            page: int = 1,  # 分页页数
            per_page: int = 10  # 每页条数
    ) -> Any:
        """
        根据条件获取已发布的文章
        """
        query = Post.query.filter(Post.deleted == 0,
                                    Post.status == 'published',
                                    Post.post_type == 'post')
        if category:
            cs = Category.query.filter(Category.deleted == 0, Category.alias == category).first()
            if cs:
                query = query.filter(Post.category_id == cs.id,
                                     Post.deleted == 0,
                                     Post.status == 'published',
                                     Post.post_type == 'post')
        if tags and len(tags) > 0:
            tags = Tag.query.filter(Tag.deleted == 0, Tag.alias.in_(tags.split(','))).all()
            post_tags = db.session.query(post_tag).filter(post_tag.c.tag_id.in_([tag.id for tag in tags]))
            if post_tags:
                query = query.filter(Post.id.in_([post_temp.post_id for post_temp in post_tags]))

        if orderby.lower() == 'asc':
            query = query.order_by(Post.published_at.asc(),
                                    Post.deleted == 0,
                                    Post.status == 'published',
                                    Post.post_type == 'post')
        elif orderby.lower() == 'desc':
            query = query.order_by(Post.published_at.desc(),
                                   Post.deleted == 0,
                                   Post.status == 'published',
                                   Post.post_type == 'post')
        else:
            query = query.order_by(Post.published_at.desc(),
                                   Post.deleted == 0,
                                   Post.status == 'published',
                                   Post.post_type == 'post')

        if type(page) != int:
            try:
                page = int(page)
            except:
                page = 1
        pg = query.paginate(page=page, per_page=per_page, error_out=False)
        if is_page:
            return pg
        else:
            return pg.items


    @app.template_global()
    def get_pages(
            json: str = None,
            orderby: str = '',  # 排序 按照发布时间 asc=升序 desc= 降序
            is_page: bool = False,  # 是否分页，如果is_page=True即开启分页,如果开启分页返回数据将是Paginate类型
            page: int = 1,  # 分页页数
            per_page: int = 10  # 每页条数
    ) -> Any:
        """
        根据条件获取已发布的文章
        """
        query = Post.query.filter(Post.deleted == 0,
                                    Post.status == 'published',
                                    Post.post_type == 'page')
        if orderby.lower() == 'asc':
            query = query.order_by(Post.published_at.asc(),
                                    Post.deleted == 0,
                                    Post.status == 'published',
                                    Post.post_type == 'page')
        elif orderby.lower() == 'desc':
            query = query.order_by(Post.published_at.desc(),
                                   Post.deleted == 0,
                                   Post.status == 'published',
                                   Post.post_type == 'page')
        else:
            query = query.order_by(Post.published_at.desc(),
                                   Post.deleted == 0,
                                   Post.status == 'published',
                                   Post.post_type == 'page')
        print("query:" + str(query))
        if type(page) != int:
            try:
                page = int(page)
            except:
                page = 1
        pg = query.paginate(page=page, per_page=per_page, error_out=False)
        if is_page:
            return pg
        else:
            return pg.items

    @app.template_global()
    def get_tags(
        post_id: int=0 # 文章ID
    ) -> Any:
        """
        根据文章ID条件获取标签，
        传ID时查询文章对应的标签，
        不传时查询所有标签
        """
        # 统计该标签关联的文章数量
        if post_id != 0:
            post_tags = db.session.query(post_tag).filter(
                post_tag.c.post_id == post_id
            ).all()
            tag_ids = []
            for post_tag_temp in post_tags:
                tag_ids.append(post_tag_temp.tag_id)
            tags = Tag.query.filter(Tag.id.in_(tag_ids)).all()
            return tags
        return Tag.query.all()

    @app.template_global()
    def get_tag():
        """
        根据访问的标签页URL获取标签相关内容
        """
        slug = get_slug(request.url)
        tag = Tag.query.filter(Tag.alias == slug).first()
        return tag
    @app.template_global()
    def get_article():
        """
        根据文章URL获取文章内容
        """
        # 统计该标签关联的文章数量
        slug = get_slug(request.url)
        post = Post.query.filter(Post.slug == slug).first()
        return post

    def get_slug(url):
        """
        获取URL中的slug
        """
        return url.split('/')[len(url.split('/'))-1]

    @app.template_global()
    def get_categories(
            post_id: int = 0 # 文章ID
    ) -> Any:
        """
        根据条件查询分类
        1.传文章ID时，查询文章对应的分类
        2.不传文章ID时，查询所有分类
        """

        if post_id:
            post_tags = db.session.query(post_tag).filter(
                post_tag.c.post_id == post_id
            ).all()

            post = Post.query.filter(Post.id == post_id).first()
            category = Category.query.filter(Category.id == post.category_id).first()
            return category
        elif post_id == 0:
            categories = Category.query.all()
            return categories
        else:
            return []

    @app.template_global()
    def get_category():
        """
        根据访问的分类页URL获取分类相关内容
        """
        slug = get_slug(request.url)
        category = Category.query.filter(Category.alias == slug).first()
        return category

    @app.template_global()
    def get_article_by_slug(
        slug: str
    ) -> Any:
        """
        根据文章别名获取文章
        """
        pass
    @app.template_global()
    def get_article_by_id(
        id: int
    ) -> Any:
        """
        根据文章ID获取文章
        """
        pass
    @app.template_global()
    def get_article_comments(
        post_id: int
    ) -> Any:
        """
        根据文章条件获取文章评论
        """
        pass
    @app.template_global()
    def get_article_comment_count(
        post_id: int
    ) -> Any:
        """
        根据文章条件获取文章评论数量
        """
        pass
    @app.template_global()
    def get_article_comment_by_id(
        id: int
    ) -> Any:
        """
        根据文章评论ID获取文章评论
        """
        pass
    @app.template_global()
    def get_article_comment_by_slug(
        slug: str
    ) -> Any:
        """
        根据文章评论别名获取文章评论
        """
        pass